/*jslint nomen: true */
/*global define, $, jQuery, _ */
define(function () {
    'use strict';

    return function (employeeTable) {
        var pub, priv;

        priv = {
            employees: [],
            employeeService: '/EmployeeService/api/employee',
            employeeTable: $(employeeTable).find('tbody'),
            templates: {
                employeeTemplate: _.template($('#template-employee').text()),
                errorTemplate: _.template($('#template-error').text())
            },
            updateForm: $('form#givePayrise'),
            init: function () {
                priv.updateForm.find('button[type=submit]').attr('disabled', false);

                priv.addEventHandlers();
                priv.fetchEmployees();
            },
            addEventHandlers: function () {
                priv.updateForm.on('submit', function (event) {
                    var id = Number(priv.updateForm.find('select[name=Id]').val()),
                        updatedEmployee = _.clone(pub.getEmployeeById(id)),
                        updateButton = priv.updateForm.find('button[type=submit]').attr('disabled', true);

                    event.preventDefault();

                    updatedEmployee.MarketPercentageMultiplier = priv.updateForm.find('select[name=marketMultiplier]').val();

                    jQuery.ajax(priv.employeeService + '/' + id, {
                        type: 'POST',
                        data: updatedEmployee
                    }).done(function (data) {
                        priv.updateEmployee(data);
                        priv.renderEmployees();
                        updateButton.attr('disabled', false);
                    });
                });
            },
            updateEmployee: function (updatedEmployee) {
                _.every(priv.employees, function (employee, i) {
                    if (employee.Id === updatedEmployee.Id) {
                        priv.employees[i] = updatedEmployee;
                        return false;
                    }

                    return true;
                });
            },
            fetchEmployees: function () {
                jQuery.ajax(priv.employeeService)
                    .done(function (data) {
                        priv.employees = data;
                        priv.renderEmployees();
                        priv.updateEmployeeSelectBox();
                    })
                    .fail(function (data) {
                        priv.renderError(data.responseText);
                    });
            },
            renderEmployees: function () {
                priv.employeeTable.empty();

                _.each(priv.employees, function (employee) {
                    priv.renderEmployee(employee);
                });
            },
            renderEmployee: function (employee) {
                priv.employeeTable.append(priv.templates.employeeTemplate({
                    id: employee.Id,
                    name: pub.getEmployeeName(employee),
                    level: employee.Level,
                    marketMultiplier: employee.MarketPercentageMultiplier,
                    salary: pub.getEmployeeSalary(employee)
                }));
            },
            renderError: function (errorMessage) {
                priv.employeeTable.append(priv.templates.errorTemplate({
                    errorMessage: errorMessage
                }));

                priv.updateForm.hide();
            },
            updateEmployeeSelectBox: function () {
                var select = $('form#givePayrise select[name=Id]').empty();

                _.each(priv.employees, function (employee) {
                    select.append(
                        $('<option />', {
                            value: employee.Id,
                            text: pub.getEmployeeName(employee)
                        })
                    );
                });
            }
        };

        pub = {
            getEmployeeById: function (id) {
                return _.find(priv.employees, function (employee) {
                    if (employee.Id === id) {
                        return employee;
                    }
                });
            },
            getEmployeeName: function (employee) {
                return employee.GivenName.charAt(0) + '. ' + employee.Surname;
            },
            getEmployeeSalary: function (employee) {
                if (!employee) {
                    throw 'invalid argument';
                }

                return '£' + employee.Salary;
            }
        };

        priv.init();

        return pub;
    };
});